<template>
  <el-upload
    class="avatar-uploader"
    v-model:file-list="fileList"
    :action="uploadUrl"
    :data="{
      sign: '1606559655810000',
    }"
    :headers="{
      'Access-Token': userStore.token
    }"
    name="files"
    list-type="picture-card"
    :on-success="handleAvatarSuccess"
    :on-error="handleAvatarError"
    :before-upload="beforeAvatarUpload"
    :on-preview="handlePictureCardPreview"
    :on-remove="handleRemove"
    :disabled="!allow"
  >
    <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
    <template v-slot:file="{file, index}">
      <div style="display: flex">
        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <el-icon><View /></el-icon>
          </span>

          <span
            v-if="!readonly"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><CircleClose /></el-icon>
          </span>
          <span
            v-if="file.imgIndex - 0 > 1"
            @click="move(file)"
          >
            <el-icon><Back /></el-icon>
          </span>
        </span>
      </div>
    </template>
  </el-upload>

  <el-dialog v-model="dialogVisible">
    <img w-full :src="dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

import type { UploadProps } from 'element-plus'
import { useUserStore } from '@/store/modules/user'

const userStore = useUserStore()

//接受父组件传递过来的参数
let props = defineProps({
  modelValue: Array,
  // 数量
  max: {
    type: [Number, String],
    default: 1,
  },
  // 大小 单位 MB
  size: {
    type: Number,
    default: 100,
  },
  allow: {
    type: Boolean,
    default: true
  }
})

const uploadUrl = import.meta.env.VITE_UPLOAD_SERVE
const previewUrl = import.meta.env.VITE_IMG_SERVE
const dialogImageUrl = ref('')
let $emit = defineEmits(['update:modelValue', 'upload', 'remove'])
const dialogVisible = ref(false)
const fileList = ref<UploadUserFile[]>([])
onMounted(() => {
})
watch(
  () => props.modelValue,
  (val) => {
    fileList.value = val.map(v => {
      let url = v.response? v.url : previewUrl + v.imgUrl
      return {
        ...v,
        url,
      }
    })
  },
)
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile,
  fileList
) => {
  let { status, data } = response
  if (status == 200) {
    let urls = data.map((v) => v.fileUrl)
    $emit('update:modelValue', fileList)
    $emit('upload', {urls, curIdx: fileList.length})
  }
}
const handleAvatarError = (e) => {
  let { message } = JSON.parse(e.message)
  ElMessage.error(message)
}

const alowTypes = ['image/jpeg', 'image/png', 'image/webp']
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  if (!alowTypes.includes(rawFile.type)) {
    ElMessage.error('请选择 .jpeg .png .webp 格式的文件')
    return false
  } else if (rawFile.size / 1024 / 1024 > props.size) {
    ElMessage.error(`图片大小不能超过${props.size}MB!`)
    return false
  }
  return true
}

const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  fileList.value = fileList.value.filter(v => v.id !== uploadFile.id)
  if (uploadFile.status == "success") {
    $emit('update:modelValue', fileList.value)
    $emit('remove', uploadFile)
  }
}

const move = (file, index) => {

  let upIdx = 0
  fileList.value.forEach((v, idx) => {
    if (v.id == file.id) {
      upIdx = idx
    }
  })
  
  fileList.value.forEach((v, idx) => {
    if (idx == upIdx) {
      v.imgIndex = idx
    } else if (idx == upIdx - 1) {
      v.imgIndex = idx + 1 + 1
    } else {
      v.imgIndex = idx + 1
    }
  })

  $emit('move', fileList.value)
}

const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
</script>

<style scoped>
.avatar-uploader .avatar {
  width: 100px;
  height: 100px;
  display: block;
  object-fit: cover;
}

img {
  width: 100%;
  height: 100%;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  text-align: center;
}
</style>
